#include "libGeoutils/io/serialize.h"
#include "libGeoutils/tool/datetime_tool.h"
#include "nlohmann/json.hpp"
#include <sstream>
#include <fstream>

#define CREATED_AT_KEY "created_at"

geo::io::IOBase::IOBase()
{
}

geo::io::IOBase::~IOBase()
{
}

static bool check_file_path(const std::string& path)
{
	return true;
}

bool geo::io::IOBase::toTextFile(const std::string& op_path) const
{
	try
	{
		if (!check_file_path) {
			return false;
		}

		std::stringstream ss;
		std::string out_str;
		if (IOBase::to_string(out_str)) { ss << out_str << "\n\n"; }
		if (to_string(out_str)) { ss << out_str; }

		std::ofstream ofs(op_path);
		if (ofs.is_open()) {
			ofs << ss.str();
			ofs.close();
		}
		else {
			mLastErrorMessage = "Cannot open file to write: " + op_path;
			return false;
		}

		return true;
	}
	catch (...)
	{
		mLastErrorMessage = "IOBase toTextFile catch one error!";
		return false;
	}
}

bool geo::io::IOBase::fromTextFile(const std::string& op_path) const
{
	try
	{
		if (!check_file_path) {
			return false;
		}
		return true;
	}
	catch (...)
	{
		mLastErrorMessage = "IOBase fromTextFile catch one error!";
		return false;
	}
}

bool geo::io::IOBase::toJsonFile(const std::string& op_path) const
{
	try
	{
		if (!check_file_path) {
			return false;
		}

		std::string out_str;
		to_json(out_str);

		nlohmann::json json = nlohmann::json::parse(out_str);
		json[CREATED_AT_KEY] = geo::tool::DateTime::now_str();

		std::ofstream ofs(op_path);
		if (ofs.is_open()) {
			ofs << json.dump(4);
			ofs.close();
		}
		else {
			mLastErrorMessage = "Cannot open file to write: " + op_path;
			return false;
		}

		return true;
	}
	catch (const std::exception&)
	{
		mLastErrorMessage = "IOBase toJsonFile catch one error!";
		return false;
	}
}

bool geo::io::IOBase::fromJsonFile(const std::string& op_path)
{
	try
	{
		if (!check_file_path) {
			return false;
		}
		std::ifstream ifs(op_path);
		if (!ifs.is_open()) {
			mLastErrorMessage = "Cannot open file to read: " + op_path;
			return false;
		}

		std::stringstream ss;
		ss << ifs.rdbuf();
		ifs.close();

		std::string in_str = ss.str();
		from_json(in_str);
		return true;
	}
	catch (...)
	{
		mLastErrorMessage = "IOBase fromJsonFile catch one error!";
		return false;
	}
}

std::string geo::io::IOBase::getLastErrorMessage() const
{
	return mLastErrorMessage;
}

bool geo::io::IOBase::to_string(std::string& out_str) const
{
	out_str.clear();
	std::stringstream ss;
	ss << CREATED_AT_KEY << ":\n"
		<< geo::tool::DateTime::now_str();

	out_str = ss.str();
	return true;
}

bool geo::io::IOBase::from_string(const std::string& in_str)
{
	return true;
}

bool geo::io::IOBase::to_json(std::string& out_str) const
{
	nlohmann::json json;
	json[CREATED_AT_KEY] = geo::tool::DateTime::now_str();
	out_str = json.dump();
	return true;
}

bool geo::io::IOBase::from_json(const std::string& in_str)
{
	return true;
}
